先判斷程式碼是傳統函式或箭頭函式
this 只與調用方式有關,與怎麼定義 this 無關 。
this 就會指向它,如果 this 前沒有任何物件會指向全域。( 下方會有範例 )setTimeout 為 callback function 是 simple call 的一種形式,在傳統函式寫法下 this 會指向全域,為了避免 setTimeout 的 this 指向全域可使用「 箭頭函式 」或是「 指向其他變數 」。( 最後範例 8 )this,會看外層函式的 this 指向。
var、const、let ) ,this 也會不同,要留意。var a = '全域'
function fn(params) {
console.log(params, this, window, arguments);
debugger;
}
fn(1, 2, 3);

// 執行 debugger ,開發者工具會跳到 Sources 區域 ▲
console.log(params, this, window, arguments); → 中為運行函數本身就可以執行的參數內容
params 為外部傳入的參數。
this 目前是指向 windows ,但實際在運作時可能會有很多種不同的指向,此指向會影響在使用框架時指到哪,如果想要指向特定的元件但卻指向錯誤,就會出錯。window 瀏覽器本身就存在的全域變數。arguments 傳統函式會帶入的參數,為類陣列會帶入所有傳入的參數內容。
fn(1, 2, 3); 有三個參數 arguments 會列出所有參數值。var obj = {
name: '小明',
fn: function(params) {
console.log(params, this, window, arguments);
// debugger;
}
}
obj.fn(1 , 2 , 3);
fn: 的函式程式碼與 #1 範例相同,但卻只有 this 有所不同。
{name: "小明", fn: ƒ} 為 this。
傳統函式中的
this只與調用方式有關,與怎麼定義this無關 。
大部分情境只須了解其中一種,請看下方 #4 this 的各種運用變化 | this 的判斷方式
//使用 const 與 let 結果會有所不同,所以變數someone 請使用 var 來設定全域變數。
var someone = '全域';
function callSomeone() {
console.log(this.someone);
}
callSomeone(); //這種呼叫方式稱 simple call
// output 全域。
// 如下方所述呼叫函式 callSomeone(); 時前方沒有任何物件,所以指向全域。
this 的判斷 : ( 此判斷方式以傳統函式為主,箭頭函式的判斷法請看 #5 this 陷阱 )
this 就會指向它 ( 例 : #4 );var someone = '全域';
function callSomeone() {
console.log(this.someone);
}
var obj = {
someone: '物件',
callSomeone() {
console.log(this.someone);
}
}
obj.callSomeone();
// output 物件。入上述判斷callSomeone()前方有物件 obj所以指向'物件'

// 呼叫函式時,前面有任何物件 this 就會指向它 ▲
var someone = '全域';
function callSomeone() {
console.log(this.someone);
}
var obj2 = {
someone : '物件2',
callSomeone //ES6 縮寫 ,原始為 callSomeone : callSomeone()
}
obj2.callSOmeone();
//output 物件2
callSomeone 指向 function callSomeone()。this 就會指向它,所以 this 指向變數 obj2。var someone = '全域';
function callSomeone() {
console.log(this.someone);
}
var wrapObj = {
someone: '外層物件',
callSomeone,
innerObj: {
someone: '內層物件',
callSomeone,
}
}
wrapObj.callSomeone();
wrapObj.innerObj.callSomeone();
callSomeone 皆使用函式 callSomeone()。this 就會指向它。
wrapObj.callSomeone(); → 所以 this 指向 wrapObj,輸出 外層物件。wrapObj.innerObj.callSomeone(); → 所以 this 指向 innerObj,輸出 內層物件。var someone = '全域';
function callSomeone() {
console.log(this.someone);
}
var obj3 = {
someone: `物件 3`,
fn() {
callSomeone(); //通常不會這樣去取用 this
}
}
obj3.fn();
this 與怎麼定義無關,只和調用方式有關,調用這個 fn() 內的 callSomeone() 函式時前方沒有看到任何物件,就屬於 simple call 會指向全域。
obj3.fn(); → output 全域this,結果可能會不如預期,這邊解說範例用。
var someone = '全域';
function callSomeone() {
console.log(this.someone);
}
var obj4 = {
someone: '物件 4',
fn() {
//callback function
setTimeout(function () {
console.log(this.someone);
});
}
}
obj4.fn();
this 大多會指向全域,少數會重新定義。this。MDN - 回呼函式(callback function)
obj4.fn(); → output 全域var obj = {
data: {
myName: 'hexschool',
},
getName: function () {
console.log(this.data.myName);
}
}
obj.getName();
getName: function () 為傳統函式,傳統函式的 this 都會看前方呼叫它的是誰。obj.getName(); 結果為 hexschool。var obj = {
data: {
myName: 'hexschool',
},
getName: () => {
console.log(this.data.myName);
}
}
obj.getName();
this。它會看外層函式作用域中的 this 指向,如果外層沒有函式則會指向全域。obj.getName(); 結果為 TypeError: Cannot read property 'myName' of undefined。var myName = '小明';
var obj = {
myName: '小美',
x: function () {
var myName = '小王';
setTimeout(function () {
console.log(this.myName);
}, 0);
},
y: '2',
}
obj.x();
setTimeout(function (){}) 為 callback function ( 大部分屬於 simple call 形式 ),會指向全域。obj.getName(); 結果為 小明。